package utilities;

import java.io.FileInputStream;
import java.io.IOException;

public class BitReader {
	FileInputStream fis;
	byte[] readout;
	int actualPosition;
	public BitReader(FileInputStream fis) throws IOException{
		this.fis = fis;
		readout = new byte[1];
		if (this.fis.read(readout) == -1){
			System.err.println("End of file reached - can't read");
		}
		actualPosition = 0;
	}
	
	public byte readByte() throws IOException{
		byte actualByte = readout[0];
		if (fis.read(readout) == -1){
			System.err.println("End of file reached - can't read");
		}
		byte shiftedActual = (byte)(actualByte << actualPosition);
		int shiftedActualPart = shiftedActual&0xFF;
		int readoutPart = readout[0] & 0xFF;
		byte shiftedNext = (byte)(readoutPart >> (8-actualPosition));
		return (byte)(shiftedActualPart|shiftedNext);
	}
	
	public int readByteAsInt() throws IOException{
		byte actualByte = readout[0];
		if (fis.read(readout) == -1){
			System.err.println("End of file reached - can't read");
		}
		byte shiftedActual = (byte)(actualByte << actualPosition);
		int shiftedActualPart = shiftedActual&0xFF;
		int readoutPart = readout[0] & 0xFF;
		byte shiftedNext = (byte)(readoutPart >> (8-actualPosition));
		return (shiftedActualPart|shiftedNext);
	}
	
	public int readInt() throws IOException{
		int fst = readByteAsInt();
		int sec = readByteAsInt();
		int thr = readByteAsInt();
		int frt = readByteAsInt();
		
		fst = fst << 24;
		sec = sec << 16;
		thr = thr << 8;
		
		return fst|sec|thr|frt;
	}
	
	public boolean readBit() throws IOException{
		byte actualByte = readout[0];
		int bit = (actualByte >>(7 - actualPosition))&1;
		boolean ret = false;
		if (bit == 1){
			ret = true;
		}
		actualPosition ++;
		if (actualPosition == 8){
			if (fis.read(readout) == -1){
				System.out.println("End of file reached - can't read - possibly this method is called for the last time");
			}
			actualPosition = 0;
		}
		
		return ret;
	}
	
	public char readBitAsChar() throws IOException{
		if (readBit() == true){
			return '1';
		}
		return '0';
	}
}
